﻿#include "MeasureView/UnitConvert.h"
#include "MeasureView/MeasureDataSet.h"
#include <QDebug>
#include <QtMath>
#include "MeasureView/MeasureParallelLine.h"

namespace Qly {


static double dist(QPointF p1, QPointF p2)
{
    QPointF t = p2 - p1;
    return hypot(t.x(), t.y());
}

void MeasureParallelLine::computeLengthSlope()
{
    m_length_pix = hypot( m_keyPoints_pix[0].x() - m_keyPoints_pix[1].x(), m_keyPoints_pix[0].y() - m_keyPoints_pix[1].y() );
    m_length_um = hypot( m_keyPoints_um[0].x() - m_keyPoints_um[1].x(), m_keyPoints_um[0].y() - m_keyPoints_um[1].y() );
    if( m_keyPoints_pix[0].x() == m_keyPoints_pix[1].x() ) // 也包括了  m_length == 0 的情况，下面就不需要特殊处理了
    {
        m_cos_theta = 0.0;
        m_sin_theta  = 1.0;
    }
    else
    {
        m_cos_theta = ( m_keyPoints_pix[1].x() - m_keyPoints_pix[0].x() ) / m_length_pix;
        m_sin_theta = ( m_keyPoints_pix[1].y() - m_keyPoints_pix[0].y() ) / m_length_pix;
    }
    double detx = m_cos_theta*5000;
    double dety = m_sin_theta*5000;
    m_keyPoints_pix[6] = m_keyPoints_pix[0] + QPointF(detx, dety);
    m_keyPoints_pix[7] = m_keyPoints_pix[0] - QPointF(detx, dety);
}

void MeasureParallelLine::setSecondLine(QPointF point_pix, QPointF point_um)
{
    m_keyPoints_pix[2].setX(point_pix.x() - m_length_pix / 2.0 * m_cos_theta);
    m_keyPoints_pix[2].setY(point_pix.y() - m_length_pix / 2.0 * m_sin_theta);
    m_keyPoints_pix[3].setX(point_pix.x() + m_length_pix / 2.0 * m_cos_theta);
    m_keyPoints_pix[3].setY(point_pix.y() + m_length_pix / 2.0 * m_sin_theta);

    m_keyPoints_um[2].setX(point_um.x() - m_length_um / 2.0 * m_cos_theta);
    m_keyPoints_um[2].setY(point_um.y() - m_length_um / 2.0 * m_sin_theta);
    m_keyPoints_um[3].setX(point_um.x() + m_length_um / 2.0 * m_cos_theta);
    m_keyPoints_um[3].setY(point_um.y() + m_length_um / 2.0 * m_sin_theta);

    m_keyPoints_um[4] = point_um;
    m_keyPoints_pix[4] = point_pix;

    m_keyPoints_um[5] = endPoint(m_keyPoints_um[0], m_keyPoints_um[1], point_um);
    m_keyPoints_pix[5] = endPoint(m_keyPoints_pix[0], m_keyPoints_pix[1], point_pix);

    double detx = m_cos_theta*5000;
    double dety = m_sin_theta*5000;
    m_keyPoints_pix[8] = m_keyPoints_pix[2] + QPointF(detx, dety);
    m_keyPoints_pix[9] = m_keyPoints_pix[2] - QPointF(detx, dety);
}

MeasureParallelLine::MeasureParallelLine(MeasureDataSet *parent)
    :MeasureElement(parent)
{
    m_cos_theta  = 1.0;
    m_sin_theta = 0.0;
    m_measureType = ParallelLine;
    m_results_pix.resize(1);
    m_results_um.resize(1);
    m_keyPoints_um.resize(10);
    m_keyPoints_pix.resize(10);
    m_textTemplate = parent->m_textTemplate_MeasureParalleLine;
}

QPointF MeasureParallelLine::endPoint(QPointF lineS, QPointF lineE, QPointF p)
{
    //计算直线外一点在直线上的垂足
    //点P(X,Y)在直线Ax+By+C=0上的垂足为
    //x=(B*B*X-A*B*Y-A*C)/(A*A+B*B)
    //y=(-A*B*X+A*A*Y-B*C)/(A*A+B*B)
    //直线公式(x-x1)/(x2-x1)=(y-y1)/(y2-y1)--》(y2-y1)x+(x1-x2)y-x1(y2-y1)+y1(x2-x1)=0
    double A = lineE.y() - lineS.y();
    double B = lineS.x() - lineE.x();
    double C = - lineS.x() * A - lineS.y() * B;
    double x = (B * B * p.x()- A * B * p.y() - A * C)/(A * A + B * B);
    double y = (-A * B * p.x() + A * A  * p.y() - B * C) / (A * A + B * B);

    return QPointF(x, y);
}
int Qly::MeasureParallelLine::mouseLButtonPress(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_IDLE )
    {
        m_keyPoints_pix[0] = point_pix;
        m_keyPoints_um[0] = point_um;
        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[1] = point_um;
        m_measureState = DS_STATE1;
        qDebug() << "DS_STATE1";
    }
    else if(m_measureState == DS_STATE1)
    {
        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[1] = point_um;
        computeLengthSlope();

        m_keyPoints_pix[2] = m_keyPoints_pix[0];
        m_keyPoints_um[2] = m_keyPoints_um[0];
        m_keyPoints_pix[3] = point_pix;
        m_keyPoints_um[3] = point_um;

        m_measureState = DS_STATE2;
        qDebug() << "DS_STATE2";
    }
    else if(m_measureState == DS_STATE2)
    {
        setSecondLine(point_pix, point_um);
        compute();
        m_measureState = DS_FINISH;
        qDebug() << "DS_FINISH";

        updateText();
    }
    return m_measureState;
}

int MeasureParallelLine::mouseMove(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_STATE1 )
    {
        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[1] = point_um;
    }
    else if(m_measureState == DS_STATE2)
    {
        setSecondLine(point_pix, point_um);
        compute();
        updateText();
    }
    return m_measureState;
}

void MeasureParallelLine::compute()
{
    //两条直线的距离，可以转换为一点到一条直线的距离
    //点P(X,Y)到直线Ax+By+C=0的距离为          |AX+BY+C|  除以 根号下(A^2+B^2)
    //直线公式(x-x1)/(x2-x1)=(y-y1)/(y2-y1)--》(y2-y1)x+(x1-x2)y-x1(y2-y1)+y1(x2-x1)=0
    //////////////////////////////////////////////////////////////////////////
    double A = m_keyPoints_um[1].y() - m_keyPoints_um[0].y();
    double B = m_keyPoints_um[0].x() - m_keyPoints_um[1].x();
    double C = - m_keyPoints_um[0].x() * A - m_keyPoints_um[0].y() * B;

    m_results_um[0] = abs(A * m_keyPoints_um[2].x() + B * m_keyPoints_um[2].y() + C ) / hypot(A, B);

    A = m_keyPoints_pix[1].y() - m_keyPoints_pix[0].y();
    B = m_keyPoints_pix[0].x() - m_keyPoints_pix[1].x();
    C = - m_keyPoints_pix[0].x() * A - m_keyPoints_pix[0].y() * B;
    m_results_pix[0] = abs(A * m_keyPoints_pix[2].x() + B * m_keyPoints_pix[2].y() + C ) / hypot(A, B);

}

void MeasureParallelLine::updateText(bool updatePosition)
{
    QString text = m_textTemplate;
//    qDebug() << m_results_um[0];
    m_pParent->m_unitConvert_MeasureParallelLine.replaceLength(text, m_results_um[0], "@length", "@unit");

    QString valueStr = QString::number(m_id);
    text.replace("@id", valueStr, Qt::CaseSensitive);

    m_textBlock.setText(text);

    if(updatePosition)
    {
        QPointF p_pix = (m_keyPoints_pix[0] + m_keyPoints_pix[1]) / 2 ;
        QPointF p_um = (m_keyPoints_um[0] + m_keyPoints_um[1]) / 2;
        m_textBlock.moveTo(p_pix, p_um);
    }
}

void MeasureParallelLine::paint(QPainter &painter)
{
    if( m_measureState != DS_IDLE )
    {
        painter.save();
        painter.setPen(m_pen);

        if(m_measureState == DS_STATE1)
        {
            drawCross(painter, m_keyPoints_pix[0]);
            drawCross(painter, m_keyPoints_pix[1]);
            painter.drawLine(m_keyPoints_pix[0], m_keyPoints_pix[1]);
        }
        else if(m_measureState == DS_STATE2)
        {
            drawCross(painter, m_keyPoints_pix[0]);
            drawCross(painter, m_keyPoints_pix[1]);
            painter.drawLine(m_keyPoints_pix[0], m_keyPoints_pix[1]);
            painter.drawLine(m_keyPoints_pix[2], m_keyPoints_pix[3]);


            QPen pen = m_pen;
            pen.setStyle(Qt::DashDotLine);
            painter.setPen(pen);
            painter.drawLine(m_keyPoints_pix[4], m_keyPoints_pix[5]);

            painter.drawLine(m_keyPoints_pix[6], m_keyPoints_pix[7]);
            painter.drawLine(m_keyPoints_pix[8], m_keyPoints_pix[9]);

            m_textBlock.draw(painter);
        }
        else if(m_measureState == DS_FINISH)
        {
            drawCross(painter, m_keyPoints_pix[0]);
            drawCross(painter, m_keyPoints_pix[1]);
            painter.drawLine(m_keyPoints_pix[0], m_keyPoints_pix[1]);
            painter.drawLine(m_keyPoints_pix[2], m_keyPoints_pix[3]);
            m_textBlock.draw(painter);
            QPen pen = m_pen;
            pen.setStyle(Qt::DashDotLine);
            painter.setPen(pen);
            painter.drawLine(m_keyPoints_pix[4], m_keyPoints_pix[5]);
            if(m_textMoving)
            {
                QPen pen = m_pen;
                pen.setStyle(Qt::DashDotLine);
                painter.setPen(pen);
                QPointF p = m_textBlock.anchorPoint();
                painter.drawLine(p, m_keyPoints_pix[4]);
                painter.setPen(m_pen);
            }
        }
        painter.restore();
    }

}

}
